package com.ecnu.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ecnu.common.core.domain.AjaxResult;
import com.ecnu.common.core.domain.entity.SysDictData;
import com.ecnu.common.core.domain.model.LoginUser;
import com.ecnu.common.utils.OtherUtil;
import com.ecnu.common.utils.StringUtils;
import com.ecnu.system.domain.*;
import com.ecnu.system.domain.dto.ProjectResultDTO;
import com.ecnu.system.domain.dto.SpectrumDTO;
import com.ecnu.system.domain.menu.OtherMenu;
import com.ecnu.system.mapper.ProjectMapper;
import com.ecnu.system.mapper.ProjectStageMissionMapper;
import com.ecnu.system.mapper.ProjectTeacherMapper;
import com.ecnu.system.mapper.SysDictDataMapper;
import com.ecnu.system.service.ISpectrumService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.map.LinkedMap;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ecnu.system.domain.menu.OtherMenu.*;

@Service
public class SpectrumServiceImpl implements ISpectrumService {
    @Autowired
    private ProjectStageMissionServiceImpl projectStageMissionService;
    @Autowired
    private ProjectStageMissionMapper stageMissionMapper;
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectTeacherMapper teacherMapper;
    @Autowired
    private ProjectSpectrumServiceImpl projectSpectrumService;
    @Autowired
    private ProjectSpectrumPathServiceImpl projectSpectrumPathService;
//    private static final String proTitle = "预期目标";
//    private static final String stageTitle = "任务目标";
//    private static final String criticalPath = "关键路径";
//    private static final String knowledge = "核心知识";
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 获取图谱信息
     *
     * @param proId
     * @param loginUser
     * @return
     */
    @Override
    public AjaxResult list(String proId, LoginUser loginUser) {
        Project project = projectMapper.selectById(proId);
        if (project == null) {
            return AjaxResult.success("活动不存在");
        }
        List<ProjectStageMission> missions = stageMissionMapper.selectList(
                new LambdaQueryWrapper<ProjectStageMission>()
                        .eq(ProjectStageMission::getStageId, proId)
                        .eq(ProjectStageMission::getDelFlag, 0)
                        .orderByAsc(ProjectStageMission::getSort));
        LambdaQueryWrapper<ProjectTeacher> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProjectTeacher::getProId, proId);
        wrapper.eq(ProjectTeacher::getTechId, loginUser.getUserId());
        List<ProjectTeacher> projectTeachers = teacherMapper.selectList(wrapper);
        boolean isUnauthorizedRole = loginUser.getUser().getRoles().stream()
                .noneMatch(role -> role.getRoleId() != 1L && role.getRoleId() != 2L);
        Long userId = null;
        if ((projectTeachers == null || projectTeachers.isEmpty()) && !isUnauthorizedRole && !project.getCreateUser().equals(String.valueOf(loginUser.getUserId()))) {
            userId = loginUser.getUserId();
        }
        ProjectResultDTO dto = new ProjectResultDTO();
        dto.setId(proId);
        List<ProjectStageMission> missionsByUser = stageMissionMapper.selectLists(dto, userId);
        LinkedMap<String, Object> linkedMap = new LinkedMap<>();

//        linkedMap.put("名称", "内容");
        //查原始数据
        LinkedMap<String, Object> atlasName = AtlasNameList(proId, missions);
        linkedMap.put("活动阶段", atlasName.get("阶段"));

        //任务目标
        LinkedMap<String, Object> expectedGoal = ExpectedGoalList(proId, project.getTitle(), missions);
        linkedMap.put(proTitle, expectedGoal.get("proTitle"));

        //任务目标
        linkedMap.put(stageTitle, expectedGoal.get("stageTitle"));

        //关键路径
        ArrayList<LinkedMap<String, Object>> criticalPathList = CriticalPathList(proId, "1");
        missionsByUser.forEach(mission -> {
            criticalPathList.forEach(map -> {
                Object idObj = map.get("stageId");
                if (idObj != null && idObj.toString().equals(mission.getId().toString())) {
                    map.put("isJoin", true);
                }
            });
        });
        linkedMap.put(criticalPath, criticalPathList);

        //知识核心
        ArrayList<LinkedMap<String, Object>> knowledgeList = CriticalPathList(proId, "2");
        missionsByUser.forEach(mission -> {
            knowledgeList.forEach(map -> {
                Object idObj = map.get("stageId");
                if (idObj != null && idObj.toString().equals(mission.getId().toString())) {
                    map.put("isJoin", true);
                }
            });
        });
        linkedMap.put(knowledge, knowledgeList);


        linkedMap.put("能力矩阵", atlasName.get("矩阵"));//取对应


        linkedMap.put("实验资源", atlasName.get("资源"));//取对应

        return AjaxResult.success(linkedMap);
    }

    @Override
    public AjaxResult infoByLinke(String proId, Integer id, String type) {
        ProjectSpectrumPath one = projectSpectrumPathService.getOne(new LambdaQueryWrapper<ProjectSpectrumPath>()
                .eq(ProjectSpectrumPath::getProId, proId)
                .eq(ProjectSpectrumPath::getId, id)
                .eq(ProjectSpectrumPath::getType, type)
                .eq(ProjectSpectrumPath::getDelFlag, 0));
        if (one!=null) {
            Map<String, Object> map = new HashMap<>();
            map.put("data", one);
            map.put("informations",projectStageMissionService.getList(one.getFileUrl()));
            return AjaxResult.success(map);
        }
        return AjaxResult.success(one);
    }

    @Override
    public AjaxResult infoByOne(String proId, String name) {
        Project project = projectMapper.selectById(proId);
        if (project == null) {
            return AjaxResult.success("活动不存在");
        }
        if (name.equals(proTitle)) {
            LinkedMap<String, Object> expectedGoal = ExpectedGoalList(proId, project.getTitle(), new ArrayList<>());
            return AjaxResult.success(expectedGoal.get("proTitle"));
        } else if (name.equals(stageTitle)) {
            List<ProjectStageMission> missions = stageMissionMapper.selectList(
                    new LambdaQueryWrapper<ProjectStageMission>()
                            .eq(ProjectStageMission::getStageId, proId)
                            .eq(ProjectStageMission::getDelFlag, 0)
                            .orderByAsc(ProjectStageMission::getSort));
            LinkedMap<String, Object> expectedGoal = ExpectedGoalList(proId, project.getTitle(), missions);
            return AjaxResult.success(expectedGoal.get("stageTitle"));
        } else if (name.equals(criticalPath)) {
            ArrayList<LinkedMap<String, Object>> criticalPathList = CriticalPathList(proId, "1");
            return AjaxResult.success(criticalPathList);
        } else if (name.equals(knowledge)) {
            ArrayList<LinkedMap<String, Object>> knowledgeList = CriticalPathList(proId, "2");
            return AjaxResult.success(knowledgeList);
        }
        return AjaxResult.error("参数错误,请联系管理员");
    }

    @Override
    public AjaxResult insert(SpectrumDTO data) {
        try {
            Project project = projectMapper.selectById(data.getId());
            if (project == null) {
                return AjaxResult.success("活动不存在");
            }

            Map<String, Object> list = (Map<String, Object>) data.getList();
            list.forEach((key, value) -> {
                switch (key) {
                    case proTitle:
                        if (value != null && value.toString().length() > 0) {
                            ProTitleEdit(data.getId(), value);
                        }
                        break;
                    case stageTitle:
                        if (value != null && value.toString().length() > 0) {
                            StageTitleEdit(data.getId(), value);
                        }
                        break;
                    case criticalPath:
                        if (value != null && value.toString().length() > 0) {
                            CriticalPathEdit(data.getId(), value,1);
                        }
                        break;
                    case knowledge:
                        if (value != null && value.toString().length() > 0) {
                            CriticalPathEdit(data.getId(), value,2);
                        }
                        break;
                }
            });
            return AjaxResult.success("保存成功");
        }catch (Exception e){
            logger.error("图谱保存错误：" + e.getMessage());
            return AjaxResult.error("保存失败,请联系管理员；");
        }
    }

    @Override
    public AjaxResult getMatrixInfo(String proId) {
        List<ProjectStageMission> missions = stageMissionMapper.selectList(
                new LambdaQueryWrapper<ProjectStageMission>()
                        .eq(ProjectStageMission::getStageId, proId)
                        .eq(ProjectStageMission::getDelFlag, 0)
                        .orderByAsc(ProjectStageMission::getSort));

        SysDictData dictData = new SysDictData();
        dictData.setDictType("sys_capacity");
        List<SysDictData> sysDictData = dictDataMapper.selectDictDataList(dictData);

        LinkedMap<String, String> dictMap = new LinkedMap<>();
        sysDictData.forEach(item -> {
            dictMap.put(item.getDictLabel(), item.getDictValue());
        });

        List<String> strings = new ArrayList<>();
        missions.forEach(mission -> {
            String[] targets = mission.getTarget().split(",");
            for (String target : targets) {
                if (StringUtils.isNotBlank( target)  &&
                        !"null".equals(target.trim().toLowerCase())) {
                    strings.add(target.trim()+"类");
                }
            }
        });
        Map<String, Long> countMap = strings.stream()
                .collect(Collectors.groupingBy(
                        Function.identity(),
                        Collectors.counting()
                ));
        return AjaxResult.success(countMap);
    }

    private void CriticalPathEdit(String id, Object value, int i) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            //添加数据
            List<Map<String, Object>> list = (List<Map<String, Object>>) value;
            list.forEach(map -> {
                if (map.get("isDel") !=null && map.get("isDel").toString().equals("true")) {//判断是否删除的路径
                    ProjectSpectrumPath projectSpectrumPath = new ProjectSpectrumPath();
                    projectSpectrumPath.setDelFlag("1");
//                    projectSpectrumPath.setId((Integer) map.get("id"));
                    projectSpectrumPathService.update(projectSpectrumPath, new LambdaQueryWrapper<ProjectSpectrumPath>()
                            .eq(ProjectSpectrumPath::getProId, id)
                            .eq(ProjectSpectrumPath::getId, map.get("id"))
                            .eq(ProjectSpectrumPath::getType, i)
                            .eq(ProjectSpectrumPath::getDelFlag, 0));
                } else {
                    ProjectSpectrumPath projectSpectrumPath1 = new ProjectSpectrumPath();
                    projectSpectrumPath1.setDelFlag("0");
                    projectSpectrumPath1.setName(map.get("name").toString());
                    projectSpectrumPath1.setTitle(map.get("title").toString());
                    try {
                        projectSpectrumPath1.setFileUrl(map.get("fileUrl") == null ? "[]" : objectMapper.writeValueAsString(map.get("fileUrl")));
                    } catch (JsonProcessingException e) {
                        projectSpectrumPath1.setFileUrl("[]");
                        logger.error("图谱关键路径文件路径错误：" + id + "活动   " + e.getMessage());
                    }
                    projectSpectrumPath1.setSort(map.get("sort").toString());
                    projectSpectrumPath1.setType(String.valueOf(i));
                    projectSpectrumPath1.setProId(id);
                    projectSpectrumPath1.setStageId(map.get("stageId") == null ? "" : map.get("stageId").toString());
                    if (map.get("id")==null) {//新增
                        projectSpectrumPathService.save(projectSpectrumPath1);
                    }else//修改
                    {
                        projectSpectrumPath1.setId(Integer.valueOf(map.get("id").toString()));
                        projectSpectrumPathService.updateById(projectSpectrumPath1);
                    }
                }
            });

        } catch (Exception e) {
            logger.error("图谱编辑关键路径错误：" + e.getMessage());
        }
    }

    private void StageTitleEdit(String id, Object value) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();

            ProjectSpectrum one = projectSpectrumService.getOne(
                    new LambdaQueryWrapper<ProjectSpectrum>()
                            .eq(ProjectSpectrum::getProId, id)
                            .eq(ProjectSpectrum::getDelFlag, 0));
            if (one != null) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) value;
                List<Map<String, Object>> listTitle = (List<Map<String, Object>>) projectStageMissionService.getList(one.getStageTitle());
                list.forEach(map -> {
                    boolean exists = false;
                    // 在现有列表中查找相同id的项
                    for (Map<String, Object> titleMap : listTitle) {
                        if (titleMap.get("id") != null &&
                                titleMap.get("id").toString().equals(map.get("id").toString())) {
                            // 找到相同id，更新title字段
                            titleMap.put("title", map.get("title"));
                            exists = true;
                            break;
                        }
                    }
                    // 没有找到相同id，添加新项
                    if (!exists) {
                        listTitle.add(map);
                    }
                });
                String valueStr = listTitle == null ? "[]" : objectMapper.writeValueAsString(listTitle);//任务清单==>object转成string
                one.setStageTitle(valueStr);
                projectSpectrumService.updateById(one);
            } else {
                String valueStr = value == null ? "[]" : objectMapper.writeValueAsString(value);//任务清单==>object转成string
                ProjectSpectrum spectrum = new ProjectSpectrum();
                spectrum.setProId(id);
                spectrum.setStageTitle(valueStr);
                projectSpectrumService.save(spectrum);
            }
        } catch (Exception e) {
            logger.error("图谱编辑任务目标错误：" + e.getMessage());
        }
    }

    private void ProTitleEdit(String id, Object value) {
        try {
            ProjectSpectrum one = projectSpectrumService.getOne(
                    new LambdaQueryWrapper<ProjectSpectrum>()
                            .eq(ProjectSpectrum::getProId, id)
                            .eq(ProjectSpectrum::getDelFlag, 0));
            if (one != null) {
                one.setProTitle(value.toString());
                projectSpectrumService.updateById(one);
            } else {
                ProjectSpectrum spectrum = new ProjectSpectrum();
                spectrum.setProId(id);
                spectrum.setProTitle(value.toString());
                projectSpectrumService.save(spectrum);
            }
        } catch (Exception e) {
            logger.error("图谱编辑预期目标错误：" + e.getMessage());
        }

    }

    private LinkedMap<String, Object> ExpectedGoalList(String proId, String title, List<ProjectStageMission> missions) {
        ProjectSpectrum one = projectSpectrumService.getOne(
                new LambdaQueryWrapper<ProjectSpectrum>()
                        .eq(ProjectSpectrum::getProId, proId)
                        .eq(ProjectSpectrum::getDelFlag, 0));
//        List<ProjectStageMission> missions = projectStageMissionMapper.selectList(
//                new LambdaQueryWrapper<ProjectStageMission>()
//                        .eq(ProjectStageMission::getStageId, proId)
//                        .eq(ProjectStageMission::getDelFlag, 0)
//                        .orderByAsc(ProjectStageMission::getSort));
        if (one != null) {
            List<Map<String, Object>> list = (List<Map<String, Object>>) projectStageMissionService.getList(one.getStageTitle());
            List<Map<String, Object>> orderedList = new ArrayList<>();

            missions.forEach(mission -> {
                // 在现有列表中查找匹配的mission
                Optional<Map<String, Object>> existingItem = list.stream()
                        .filter(map -> {
                            Object idObj = map.get("id");
                            return idObj != null && idObj.toString().equals(mission.getId().toString());
                        })
                        .findFirst();

                if (existingItem.isPresent()) {
                    // 如果找到了，直接使用现有的项
                    orderedList.add(existingItem.get());
                } else {
                    // 如果没找到，创建新的项并添加
                    LinkedMap<String, Object> missionMap = new LinkedMap<>();
                    missionMap.put("id", mission.getId());
                    missionMap.put("name", mission.getMissionName());
                    missionMap.put("title", mission.getDescription());
                    missionMap.put("sort", mission.getSort());
                    orderedList.add(missionMap);
                }
            });
            list.sort(Comparator.comparing(map -> (Integer) map.get("sort")));
            LinkedMap<String, Object> linkedMap = new LinkedMap<>();
            linkedMap.put("proId", one.getProId());
            linkedMap.put("proTitle", one.getProTitle());
            linkedMap.put("stageTitle", orderedList);//转list
            return linkedMap;
        } else {
            ArrayList<LinkedMap<String, Object>> linkedMaps = new ArrayList<>();
            missions.forEach(mission -> {
                LinkedMap<String, Object> missionMap = new LinkedMap<>();
                missionMap.put("id", mission.getId());
                missionMap.put("name", mission.getMissionName());
                missionMap.put("title", mission.getDescription());
                missionMap.put("sort", mission.getSort());
                linkedMaps.add(missionMap);
            });
            ObjectMapper objectMapper = new ObjectMapper();
            String s = "";
            try {
                s = linkedMaps == null ? "[]" : objectMapper.writeValueAsString(linkedMaps);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            LinkedMap<String, Object> linkedMap = new LinkedMap<>();
            linkedMap.put("proId", proId);
            linkedMap.put("proTitle", getFirstPTextWithLength(title,254));
            linkedMap.put("stageTitle", linkedMaps);
            return linkedMap;
        }
    }
    public static String getFirstPTextWithLength(String html, int maxLength) {
        if (html == null || html.trim().isEmpty()) {
            return "";
        }

        Document doc = Jsoup.parse(html);
        Element firstP = doc.select("p").first();

        if (firstP == null) {
            return ""; // 没有找到 <p> 标签
        }

        String text = firstP.text();
        if (text.length() <= maxLength) {
            return text;
        } else {
            return text.substring(0, maxLength);
        }
    }
    private ArrayList<LinkedMap<String, Object>> CriticalPathList(String proId, String i) {
        List<ProjectSpectrumPath> list = projectSpectrumPathService.list(new LambdaQueryWrapper<ProjectSpectrumPath>()
                .eq(ProjectSpectrumPath::getProId, proId)
                .eq(ProjectSpectrumPath::getType, i)
                .eq(ProjectSpectrumPath::getDelFlag, "0")
                .orderByAsc(ProjectSpectrumPath::getSort));
        ArrayList<LinkedMap<String, Object>> linkedMaps = new ArrayList<>();
        list.forEach(path -> {
            LinkedMap<String, Object> linkedMap = new LinkedMap<>();
            linkedMap.put("id", path.getId());
            linkedMap.put("stageId", path.getStageId());
            linkedMap.put("name", path.getName());
            linkedMap.put("sort", path.getSort());
            linkedMap.put("isJoin", false);//是否参与
            linkedMaps.add(linkedMap);
        });
        return linkedMaps;
    }

    private LinkedMap<String, Object> AtlasNameList(String proId, List<ProjectStageMission> missions) {
        LinkedMap<String, Object> linkedMap = new LinkedMap<>();
        List<LinkedMap<String, Object>> missionList = new ArrayList<>();
        missions.forEach(mission -> {
            LinkedMap<String, Object> missionMap = new LinkedMap<>();
            missionMap.put("id", mission.getId());
            missionMap.put("name", mission.getMissionName());
            missionMap.put("sort", mission.getSort());
            String time = "0";
            if (mission.getStartTime() != null && mission.getStartTime().after(new Date())) {
                time = "0";
            } else if (mission.getEndTime() != null && mission.getEndTime().before(new Date())) {
                time = "-1";
            } else {
                time = "1";
            }
            missionMap.put("isTimeNow", time);//-1 已过，0即将开始，1进行中
            missionList.add(missionMap);
        });
        linkedMap.put("阶段", missionList);

        SysDictData dictData = new SysDictData();
        dictData.setDictType("sys_capacity");
        List<SysDictData> sysDictData = dictDataMapper.selectDictDataList(dictData);
        LinkedMap<String, String> dictMap = new LinkedMap<>();
        sysDictData.forEach(item -> {
            dictMap.put(item.getDictLabel(), item.getDictValue());
        });

        List<LinkedMap<String, Object>> matrixList = new ArrayList<>();
        missions.forEach(mission -> {
            LinkedMap<String, Object> list = new LinkedMap<>();
            list.put("id", mission.getId());
            LinkedMap<String, String> matrixMap = new LinkedMap<>();
            String[] targets = mission.getTarget().split(",");

            for (String target : targets) {
                if (StringUtils.isNotBlank(target)) {
                    String dictValue = dictMap.entrySet().stream()
                            .filter(entry -> entry.getKey().contains(target))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .orElse("暂无解释");

                    matrixMap.put(target, dictValue);
                }else {
                    matrixMap.put("","未指定能力指标");
                }
            }
            list.put("matrix", matrixMap);
            matrixList.add(list);
        });
        linkedMap.put("矩阵", matrixList);

        List<LinkedMap<String, Object>> resourceList = new ArrayList<>();
        missions.forEach(mission -> {
            LinkedMap<String, Object> map = new LinkedMap<>();
            map.put("name", mission.getMissionName());
            map.put("tools", mission.getTool());
            map.put("sort", mission.getSort());
            resourceList.add(map); // 将map添加到列表中
        });
        linkedMap.put("资源", resourceList);
        return linkedMap;
    }
}
